var currentObj = null;
var flowId = 0;
var typeCommon = "c";
var typeSkip = "s";
var typeMutiSkip = "m";
var canSaveFlow = false;
var resetToOld = false;
var flowIsFix = true;//当前填写的流程是否完整

/**
 * jsPlumb关键点就是连接线
 *  Anchor：锚点位置
 Endpoint：端点，连接的起点或终点
 Connector：连线，连接两个节点的直观表现，有四种默认类型：Bezier（贝塞尔曲线），Straight（直线），Flowchart（流程图），State machine（状态机）
 Overlay：装饰连接器的组件，类似箭头之类
 Group：包含在某个其他元素中的一组元素，可以折叠，导致与所有组成员的连接被合并到折叠的组容器上。
 * */
jsPlumb.ready(function () {
    var instance = window.jsp = jsPlumb.getInstance({
        // default drag options
        DragOptions: {cursor: 'pointer', zIndex: 2000},//拖动
        // the overlays to decorate each connection with.  note that the label overlay uses a function to generate the label text; in this
        // case it returns the 'labelText' member that we set on each connection in the 'init' method below.
        ConnectionOverlays: [
            //覆盖物连接线的样式 箭头
            ["Arrow", {
                location: 1, visible: true, width: 11, length: 11, id: "ARROW",
                events: {
                    click: function () {
                        // alert("you clicked on the arrow overlay")
                    }
                }
            }]
            //在连接点的可配置标签
            /* ,[ "Label", { location: 0.1,id: "label",cssClass: "aLabel",
                 events:{
                    // tap:function() { alert("hey"); }
                 }
             }]*/
        ],
        Container: "canvas"
    });

    var basicType = {
        connector: "StateMachine",
        paintStyle: {stroke: "red", strokeWidth: 5},
        hoverPaintStyle: {stroke: "blue"},
        overlays: ["Arrow"]
    };
    //动态的修改连接线或端点的样式
    instance.registerConnectionType("basic", basicType);

    //连接线样式 this is the paint style for the connecting lines..
    var connectorPaintStyle = {
            strokeWidth: 3,
            stroke: "#61B7CF",
            joinstyle: "round",
            outlineStroke: "white",
            outlineWidth: 3
        },
        //鼠标选中，连接线的样式 .. and this is the hover style.
        connectorHoverStyle = {
            strokeWidth: 2,
            stroke: "#216477",
            outlineWidth: 3,
            outlineStroke: "white"
        },
        //鼠标选中，连接线的样式
        endpointHoverStyle = {
            fill: "#216477",
            stroke: "#216477"
        },
        //连接点 半径为2的圆 the definition of sorce endpoints (the small blue ones)
        sourceEndpoint = {
            endpoint: "Dot",
            paintStyle: {
                stroke: "#7AB02C",
                fill: "transparent",
                radius: 3,
                strokeWidth: 1
            },
            isSource: true,
            //连接线的样式种类有[Bezier],[Flowchart],[StateMachine ],[Straight ]
            connector: ["Flowchart", {stub: [40, 60], gap: 10, cornerRadius: 5, alwaysRespectStubs: true}],
            connectorStyle: connectorPaintStyle,
            hoverPaintStyle: endpointHoverStyle,
            connectorHoverStyle: connectorHoverStyle,
            dragOptions: {},
            overlays: [
                ["Label", {
                    location: [0.5, 1.5],
                    label: "Drag",
                    cssClass: "endpointSourceLabel",
                    visible: false
                }]
            ]
        },
        //被连接点 the definition of target endpoints (will appear when the user drags a connection)
        targetEndpoint = {
            endpoint: "Dot",
            paintStyle: {fill: "#7AB02C", radius: 4},
            hoverPaintStyle: endpointHoverStyle,
            maxConnections: -1,
            dropOptions: {hoverClass: "hover", activeClass: "active"},
            isTarget: true,
            overlays: [
                ["Label", {location: [0.5, -0.5], label: "Drop", cssClass: "endpointTargetLabel", visible: false}]
            ]
        },
        /*连线后触发*/
        init = function (connection) {
            if (conn.sourceId.indexOf(conn.targetId) != -1) {
                alert("不能让以自己为目标元素");
                instance.detach(connection);
                return false;
            }
            connection.getOverlay("label").setLabel(connection.sourceId.substring(15) + "-" + connection.targetId.substring(15));
        };

    //添加连接点
    var _addEndpoints = function (toId, sourceAnchors, targetAnchors) {
        for (var i = 0; i < sourceAnchors.length; i++) {
            var sourceUUID = toId + sourceAnchors[i];
            instance.addEndpoint(/*"flowchart" + */toId, sourceEndpoint, {
                anchor: sourceAnchors[i], uuid: sourceUUID
            });
        }
        for (var j = 0; j < targetAnchors.length; j++) {
            var targetUUID = toId + targetAnchors[j];
            instance.addEndpoint(/*"flowchart" + */toId, targetEndpoint, {anchor: targetAnchors[j], uuid: targetUUID});
        }
    };


    //绘图 suspend drawing and initialise.
    instance.batch(function () {
        /*_addEndpoints("flowchartWindow41", ["TopCenter", "BottomCenter"], ["LeftMiddle", "RightMiddle"]);
        _addEndpoints("flowchartWindow21", ["LeftMiddle", "BottomCenter"], ["TopCenter", "RightMiddle"]);
        _addEndpoints("flowchartWindow31", ["RightMiddle", "BottomCenter"], ["LeftMiddle", "TopCenter"]);
        _addEndpoints("flowchartWindow11", ["LeftMiddle", "RightMiddle"], ["TopCenter", "BottomCenter"]);
        _addEndpoints("flowchartWindow51", ["LeftMiddle", "RightMiddle"], ["TopCenter", "BottomCenter"]);
        _addEndpoints("flowchartWindow61", ["LeftMiddle", "RightMiddle"], ["TopCenter", "BottomCenter"]);
*/

        // listen for new connections; initialise them the same way we initialise the connections at startup.
        instance.bind("connection", function (connInfo, originalEvent) {
            init(connInfo.connection);
        });

        // 获取所有的实体 使可进行拖动
        instance.draggable(jsPlumb.getSelector(".flowchart-demo .window"), {grid: [20, 20]});
        // THIS DEMO ONLY USES getSelector FOR CONVENIENCE. Use your library's appropriate selector
        // method, or document.querySelectorAll:
        //jsPlumb.draggable(document.querySelectorAll(".window"), { grid: [20, 20] });

        // connect a few up
        // instance.connect({uuids: ["flowchartWindow2BottomCenter", "flowchartWindow1TopCenter"], editable: true});
        // instance.connect({uuids: ["flowchartWindow2LeftMiddle", "flowchartWindow4LeftMiddle"], editable: true});
        // instance.connect({uuids: ["flowchartWindow4TopCenter", "flowchartWindow3RightMiddle"], editable: true});
        // instance.connect({uuids: ["flowchartWindow3RightMiddle", "flowchartWindow2RightMiddle"], editable: true});
        // instance.connect({uuids: ["flowchartWindow4BottomCenter", "flowchartWindow1TopCenter"], editable: true});
        // instance.connect({uuids: ["flowchartWindow5BottomCenter", "flowchartWindow6BottomCenter"], editable: true});
        //

        // listen for clicks on connections, and offer to delete connections on click.
        instance.bind("click", function (conn, originalEvent) {
            // if (confirm("Delete connection from " + conn.sourceId + " to " + conn.targetId + "?"))
            //   instance.detach(conn);
            // conn.toggleType("basic");
            console.log("连线关系后，点击线条不作改变");
        });

        instance.bind("connectionDrag", function (connection) {
            console.log("connection " + connection.id + " is being dragged. suspendedElement is ", connection.suspendedElement, " of type ", connection.suspendedElementType);
        });

        instance.bind("connectionDragStop", function (connection) {
            console.log("connection " + connection.id + " was dragged");
        });

        instance.bind("connectionMoved", function (params) {
            console.log("connection " + params.connection.id + " was moved");
        });
    });

    jsPlumb.fire("jsPlumbDemoLoaded", instance);

    //新增节点
    $(document).on('click', '#add_nomal', function (e) {
        // var i = speakingSkillList.length + 1+"_"+version;
        var oldObj = null;//是否是已存在的对象
        $.each(speakingSkillList, function () {
            if (this.id == currentObj.id) {
                oldObj = this;
                return;
            }
        });

        if (currentObj != null) {
            var btnSize = (currentObj.answerTypes!=null && currentObj.answerTypes.length>0)?currentObj.answerTypes.length:4;
            var divWidth = 200;
            if(btnSize>4){
                divWidth = divWidth + (btnSize-4)*65;
            }
            console.log("divWidth======================"+divWidth);
            if (oldObj == null) {
                var id = currentObj.id + prefixVersion + version;
                var objStr = '<div id="' + id + '" class="window nomalNode jtk-node" style="width:'+divWidth+'px;height:125px;padding: 5px 5px;">\n' +
                    '                    <div class="title" name="title" style="position:absolute;top:10px;left:5px;right:5px;text-align:center;color: #009688;font-weight: bold;font-size: larger;width: 100%;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;">' + currentObj.name + '</div>' +
                    '                    <div class="conent" name="conent" style="text-overflow:ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;position: absolute;top: 40px;left: 5px;right: 5px">' + currentObj.content + '</div>\n' +
                    '                    <div class="btns" name="btns"  style="position:absolute;bottom:10px;left:5px;right: 5px;"><div class="divButton" style="text-align: center">\n';

                if (currentObj.answerTypes != null && currentObj.answerTypes.length > 0) {
                    for (var i = 0; i < currentObj.answerTypes.length; i++) {
                        var btnId = currentObj.id + "_" + currentObj.answerTypes[i].key + prefixVersion + version;
                        objStr += '<a id=\"' + btnId + '" class=\"layui-btn layui-btn-xs\"  >' + currentObj.answerTypes[i].value + '</a>\n';
                    }
                }
                objStr += "</div></div></div>";
                var $item = $(objStr);
                $("#canvas").append($item);
                instance.draggable($item);
                var bts = "";
                $item.find(".divButton").children().each(function (idx, elem) {
                    var elem = $(elem);
                    _addEndpoints(elem.attr("id"), ["BottomCenter"], []);
                    bts += elem.attr("id") + ":" + elem.text() + ",";
                });
                _addEndpoints($item.attr("id"), [], ["TopCenter", "LeftMiddle", "RightMiddle", "BottomCenter"]);
                /* var name = $item.find(".title").text();
                 var conent = $item.find(".conent").text();*/
                speakingSkillList.push(currentObj);
            } else {
                exportCurrentFlow();
                updateSpeakingSkillList(currentObj);
                /* var id = currentObj.id + prefixVersion + version;
                 $(".flowchart-demo").children().each(function(idx, elem) {
                     var elem = $(elem);
                     if (elem.hasClass('jtk-node')) {
                         var nodeId = elem.attr('id');
                         if(id == nodeId){
                             elem.children().each(function () {
                                 if($(this).attr("name")=="title"){
                                     $(this).html(currentObj.name);
                                 }else if($(this).attr("name")=="conent"){
                                     $(this).html(currentObj.content);
                                 }else if($(this).attr("name")=="btns"){
                                     $(this).children().each(function (idx, btnDiv) {
                                         var btnDiv = $(btnDiv);
                                         if(btnDiv==undefined){
                                             return;
                                         }
                                         // btnDiv.empty();//情况btn Div 的内容
                                         //移除原有的节点
                                         for (var i = 0; i < currentObj.answerTypes.length; i++) {
                                             var btnId = currentObj.id + "_" + currentObj.answerTypes[i].key + prefixVersion + version;
                                             btnDiv.append('<a id=\"' + btnId + '" class=\"layui-btn layui-btn-xs\"  >' + currentObj.answerTypes[i].value + '</a>\n');//新增一个按钮对象
                                             _addEndpoints(btnId, ["BottomCenter"], []);//为按钮添加连接点
                                             var sourceConn = instance.getConnections({ source: btnId});//根据连接点id来获取连接关系
                                             $.each(sourceConn, function (scopeName, conn) {
                                                 var sourceConnectLocation,targetConnectLocation;
                                                 $.each(conn.endpoints,function (scopeName,point) {
                                                     if(point.elementId == conn.sourceId){
                                                         sourceConnectLocation = point.anchor.type;
                                                     }
                                                     if(point.elementId == conn.targetId){
                                                         targetConnectLocation = point.anchor.type;
                                                     }
                                                 });
                                                 // instance.deleteConnection(conn);//移除原有的连接关系
                                                 // instance.connect({uuids: [conn.sourceId+sourceConnectLocation, conn.targetId+targetConnectLocation], editable: true});//新增一条连接关系
                                             });
                                         }
                                     });
                                 }
                             });
                         }
                     }
                 });*/
            }
        }
        currentObj = null;//重置对象
    });

    //新增跳转节点
    $(document).on('click', "#add_redirect", function (e) {
        // var i = speakingSkillList.length + 1+"_"+version;
        var oldObj = null;//是否是已存在的对象
        $.each(speakingSkillList, function () {
            if (this.id == currentObj.id) {
                oldObj = this;
                return;
            }
        });

        if (currentObj != null) {
            if (oldObj == null) {
                var id = currentObj.id + prefixVersion + version;
                var nextflowName = currentObj.nextflowName;
                var $item = $('<div id="' + id + '" class="window redirectNode jtk-node " style="width:200px;height:125px;padding: 5px 5px;" >\n' +
                    '                    <div class="title" style="position:absolute;top:10px;left:5px;right:5px;color: #009688;font-weight: bold;font-size: larger;width: 100%;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;">' + currentObj.name + '</div>\n' +
                    '                    <div class="conent" style="text-overflow:ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;position: absolute;top: 40px;left: 5px;right: 5px">' + currentObj.content + '</div>\n' +
                    '                    <div style="position:absolute;bottom:10px;left:5px;color: #009688;font-weight: bold;font-size: larger;">跳转到:' + nextflowName + '</div>\n' +
                    '                </div>');
                $("#canvas").append($item);
                _addEndpoints($item.attr("id"), [], ["TopCenter", "LeftMiddle", "RightMiddle", "BottomCenter"]);
                // var name = $item.find(".title").text();
                // var conent = $item.find(".conent").text();
                // speakingSkillList.push(SkipObj.buildParam($item.attr("id"),0,0,name,"",conent));
                instance.draggable($item);
                speakingSkillList.push(currentObj);
            } else {
                exportCurrentFlow();
                updateSpeakingSkillList(currentObj);
                // updateSpeakingSkillList(currentObj);
            }
        }
        currentObj = null;//重置对象
        /**
         var $item = $('<div id="redirect_'+i+'" class="window redirectNode jtk-node " style="width:300px;height:150px;padding: 5px 5px;" >\n' +
         '                    <div class="title" style="position:absolute;top:10px;left:5px;color: #009688;font-weight: bold;font-size: larger;">跳转话术</div>\n' +
         '                    <div class="conent">好的，我给你详细介绍一下！</div>\n' +
         '                    <div style="position:absolute;bottom:10px;left:5px;color: #009688;font-weight: bold;font-size: larger;">跳转到:下一个主动流程</div>\n' +
         '                </div>');
         $("#canvas").append($item);
         _addEndpoints($item.attr("id"), [],["TopCenter","LeftMiddle","RightMiddle","BottomCenter"]);
         var name = $item.find(".title").text();
         var conent = $item.find(".conent").text();
         speakingSkillList.push(SkipObj.buildParam($item.attr("id"),0,0,name,"",conent));
         instance.draggable($item);
         */
    });

    $(document).on('click', '#saveFlow', function (e) {
        exportCurrentFlow();
        if (canSaveFlow == true) {
            saveFlow();
        }else{
            if(flowIsFix == false){
                layer.msg("检测当前流程不完整，无法进行此操作");
                return;
            }else{
                layer.msg("没有相关的流程数据，无法进行此操作");
                return;
            }
        }
    });

    //导出当前流程的结果图
    /**
     * speakingSkillList  用于存放节点对象 ===》当添加节点时，将节点对象push在该集合中
     * $(".flowchart-demo").children()  获取当前画布中的元素节点
     * 有效节点 ======》 有和speakingSkillList集合中节点元素的id一致
     * 无效节点 ======》 虽添加了元素，但在画布中被删除了 --- 视为无效
     *
     * 导出的结果集 用于后续flow对象重绘流程图用 分为 4个jsonStr  分别
     *      commonStepStr 普通节点json对象str
     *      skipStepStr 跳转节点json对象str
     *      connectPointsStr 节点的连接点json对象str [连接点==》可以线条关系连接上的点]
     *      connectRelationStr 节点的关系json对象str [关系连接点、被连接点、连接的位置]
     *
     * 根据节点元素 来进行遍历获取 节点相关的连接点、关系
     * */
    function exportCurrentFlow() {
        console.log("========================================>exportCurrentFlow");
        var commonStep = [];//普通话术
        var sikpStep = [];//跳转话术
        var connectPoints = [];//话术的连接点
        var connectRelation = [];//话术的连接关系
        var sourcePointId = [];//连接点的id集合 用于判断 普通节点中是否存在 该连接点的关系 如果不存在 ==》 得出 该流程是不完整的不给予保存操作
        var connectRelationIds = ",";//用于存连接关系，因为获取节点的关系时，多个节点的关系可能重复，所以用此对象存放push进集合的 id ,用于过滤用
        var currentVersion = prefixVersion + version;//当前版本号
        console.log(speakingSkillList);
        if ($(".flowchart-demo").children().length > 0 && speakingSkillList.length > 0) {
            $(".flowchart-demo").children().each(function (idx, elem) {
                var elem = $(elem);
                if (elem.hasClass('jtk-node')) {
                    var nodeId = elem.attr('id');
                    var selNode = null;
                    $.each(speakingSkillList, function (key, value) {
                        var obj = value;
                        if (obj != undefined && obj.id + currentVersion == nodeId) {
                            selNode = obj;
                            return;
                        }
                    });
                    /**
                     *
                     * 目前除了 普通节点下的 分支 是有 可连接点外，其余的都是被连接点===》所以取点的关系时，仅取普通分支下的连接点即可
                     //获取该节点的连接点的关系
                     var conns = instance.getConnections({source: nodeId});//获取连接点
                     $.each(conns, function (scopeName, conn) {
                        var sourceConnectLocation, targetConnectLocation;
                        $.each(conn.endpoints, function (scopeName, point) {
                            if (point.elementId == conn.sourceId) {
                                sourceConnectLocation = point.anchor.type;//连接点所在的位置
                            }
                            if (point.elementId == conn.targetId) {
                                targetConnectLocation = point.anchor.type;//被连接点所在的位置
                            }
                        });
                        var btnId = conn.id.substring(0, conn.id.indexOf(prefixVersion));
                        if (conn.id.indexOf(prefixVersion) && connectRelationIds.indexOf("," + btnId + ",") == -1) {//防止重复保存节点连接关系
                            connectRelationIds += btnId + ",";
                            // var type = conn.sourceId.replace(nodeId.replace(currentVersion,""),"");
                            var sourceId = conn.sourceId.substring(0, conn.sourceId.indexOf(prefixVersion));//去掉version
                            var type = sourceId.replace(nodeId.substring(0, nodeId.indexOf(prefixVersion)));////去掉id 和 custom_  返回指定的类型
                            var targetId = conn.targetId.substring(0, conn.targetId.indexOf(prefixVersion));//去掉version
                            connectRelation.push(ConnectRelationObj.buildParam(conn.id, sourceId, sourceConnectLocation, targetId, targetConnectLocation, type, conn.label));
                        }
                    });

                     //获取该节点的被连接点的关系
                     var targetConn = instance.getConnections({target: nodeId});
                     $.each(targetConn, function (scopeName, conn) {
                        console.log(targetConn.length);
                        var sourceConnectLocation, targetConnectLocation;
                        $.each(conn.endpoints, function (scopeName, point) {
                            if (point.elementId == conn.sourceId) {
                                sourceConnectLocation = point.anchor.type;
                            }
                            if (point.elementId == conn.targetId) {
                                targetConnectLocation = point.anchor.type;
                            }
                        });
                        console.log(conn.id);
                        var btnId = conn.id.substring(0, conn.id.indexOf(prefixVersion));
                        console.log(btnId);
                        console.log(connectRelationIds);
                        console.log(connectRelationIds.indexOf("," + btnId + ","));
                        if (conn.id.indexOf(prefixVersion) && connectRelationIds.indexOf("," + btnId + ",") == -1) {
                            connectRelationIds += btnId + ",";
                            var type = conn.sourceId.replace(nodeId.substring(0, nodeId.indexOf(prefixVersion)));////去掉id 和 custom_  返回指定的类型
                            var targetId = conn.targetId.substring(0, conn.targetId.indexOf(prefixVersion));//去掉version
                            var sourceId = conn.sourceId.substring(0, conn.sourceId.indexOf(prefixVersion));//去掉version
                            connectRelation.push(ConnectRelationObj.buildParam(conn.id, sourceId, sourceConnectLocation, targetId, targetConnectLocation, type, conn.label));
                        }
                    });
                     */
                    //获取该节点的所有连接点
                    var endPoints = instance.getEndpoints(nodeId);
                    $.each(endPoints, function (scopeName, point) {
                        var type = "";
                        if (point.isSource == "true") {
                            type = "source";
                        } else {
                            type = "target";
                        }
                        connectPoints.push(ConnectPointObj.buildParam(nodeId, type, point.anchor.type, ""));
                    });
                    if (selNode != null) {
                        selNode.x = elem.css("left");
                        selNode.y = elem.css("top");
                        if (selNode.type == typeCommon) {//普通话术  --- 取对应的button下的关系集合
                            if (selNode.answerTypes != null && selNode.answerTypes.length > 0) {
                                $.each(selNode.answerTypes, function () {
                                    //获取该节点的连接点的关系
                                    var id = selNode.id + "_" + this.key + currentVersion;
                                    var signId = selNode.id + "_" + this.key + currentVersion;
                                    var type = this.key;
                                    var sourceConn = instance.getConnections({source: signId});
                                    $.each(sourceConn, function (scopeName, conn) {
                                        var sourceConnectLocation, targetConnectLocation;
                                        $.each(conn.endpoints, function (scopeName, point) {
                                            if (point.elementId == conn.sourceId) {
                                                sourceConnectLocation = point.anchor.type;
                                            }
                                            if (point.elementId == conn.targetId) {
                                                targetConnectLocation = point.anchor.type;
                                            }
                                        });
                                        var btnId = signId.substring(0, signId.indexOf(prefixVersion));
                                        // console.log(btnId);
                                        // console.log(connectRelationIds);
                                        // console.log(connectRelationIds.indexOf("," + btnId + ","));
                                        if (signId.indexOf(prefixVersion) && connectRelationIds.indexOf("," + btnId + ",") == -1) {//防止重复保存节点连接关系
                                            var sourceId = conn.sourceId.substring(0, conn.sourceId.indexOf(prefixVersion));//去掉version
                                            var type = conn.sourceId.replace(nodeId.substring(0, nodeId.indexOf(prefixVersion)));////去掉id 和 custom_  返回指定的类型
                                            var targetId = conn.targetId.substring(0, conn.targetId.indexOf(prefixVersion));//去掉version
                                            connectRelationIds += btnId + ",";
                                            connectRelation.push(ConnectRelationObj.buildParam(btnId, sourceId, sourceConnectLocation, targetId, targetConnectLocation, type, conn.label));
                                            sourcePointId.push(sourceId);
                                        }
                                    });

                                    //获取该节点的所有连接点
                                    var endPoints = instance.getEndpoints(signId);
                                    $.each(endPoints, function (scopeName, point) {
                                        var type = "";
                                        if (point.isSource == true) {
                                            type = "source";
                                        } else {
                                            type = "target";
                                        }
                                        connectPoints.push(ConnectPointObj.buildParam(signId, type, point.anchor.type, ""));
                                    });
                                });
                            }
                            commonStep.push(selNode);
                        } else {
                            sikpStep.push(selNode)
                        }
                    }
                }
            });
            commonStepStr = JSON.stringify(commonStep);
            skipStepStr = JSON.stringify(sikpStep);
            connectPointsStr = JSON.stringify(connectPoints);
            connectRelationStr = JSON.stringify(connectRelation);
            flowIsFix = true;
            $.each(commonStep, function (index, obj) {
                if(flowIsFix==true && obj.answerTypes!=null){
                    $.each(obj.answerTypes,function (aIdx,aObj) {
                        console.log(obj.id+"_"+aObj.key);
                        console.log($.inArray(obj.id+"_"+aObj.key, sourcePointId));
                        if(flowIsFix == true && $.inArray(obj.id+"_"+aObj.key, sourcePointId)==-1){
                            flowIsFix = false;
                        }
                    })
                }
            });
            if(flowIsFix==false){
                canSaveFlow = false;
            }else{
                canSaveFlow = true;
            }
        } else {
            commonStepStr = "";
            skipStepStr = "";
            connectPointsStr = "";
            connectRelationStr = "";
            canSaveFlow = false;
        }
        console.log("========================================>exportCurrentFlow end");
    }

    $(document).on('click',"#resetOld",function (e) {
        resetToOld = true;
        $("#reset").click();
    });

    //还原结果集 --->绘图
    /**
     *   var blocks=[];//话术
     var connectPoints =[];//话术的连接点
     var connectRelation=[];//话术的连接关系
     * */
    $(document).on('click', '#reset', function (e) {
        // speakingSkillList = [];
        if ($(".flowchart-demo").children().length > 0 && speakingSkillList.length > 0) {
            // instance.reset();//关系节点移除
            $(".flowchart-demo").children().each(function (idx, elem) {
                var elem = $(elem);
                if (elem.hasClass('jtk-node')) {
                    delNode(elem);
                }
            });
        }
        speakingSkillList = [];
        if (seletFlowId == "0") {
            layer.msg("请选择流程，再进行添加节点操作");
            return;
        }
        var flowJsonObj = $("#" + seletFlowId);
        var jsonStr = flowJsonObj.attr("value");
        console.log("seletFlowId=====================>"+seletFlowId);
        if(resetToOld==false){ // 非还原到原来的流程时， 则按缓存中对象取
            $.each(existsFlowObjs,function (index,obj) {
                if(obj.flowId == seletFlowId){
                    jsonStr = obj.flowJsonStr;
                }
            });
        }else{
            resetToOld = false;//重置该值
        }
        if (jsonStr == null || jsonStr == "") {
            layer.msg("该流程还未添加节点数据");
            return;
        }
        var jsonObj = JSON.parse(jsonStr);

        commonStepStr = jsonObj.typeCommon;
        skipStepStr = jsonObj.typeSkip;
        connectRelationStr = jsonObj.connectRelationStr;
        connectPointsStr = jsonObj.connectPointsStr;

        var oldVersion = prefixVersion + version;
        version = version + 1;
        var newVersion = prefixVersion + version;
        //根据json数据进行重绘流程图
        $.each(JSON.parse(jsonObj.typeCommon), function (key, obj) {
            var id = obj.id;
            if (obj.id.indexOf(prefixVersion) != -1) {
                // var id = obj.id.replace(oldVersion,"")+newVersion;//初始加载时  step 的id 是没有带version的，删除节点时，再重绘是有的，所以要进行移除oldVersion
                id = id.substring(0, obj.id.indexOf(prefixVersion)) + newVersion;
            } else {
                id = id + newVersion;
            }
            var buttons = '<div class="btn" name="btns" style="position:absolute;bottom:10px;left:5px;right: 5px;"><div class="divButton" style="text-align: center">\n';
            var btnIdArray = [];
            if (obj.answerTypes != null && obj.answerTypes.length > 0) {
                for (var i = 0; i < obj.answerTypes.length; i++) {
                    buttons += '<a id=\"' + obj.id + "_" + obj.answerTypes[i].key + newVersion + '\" class=\"layui-btn layui-btn-xs\"  >' + obj.answerTypes[i].value + '</a>\n';
                }
            }
            buttons += "</div></div>\n";
            var btnSize = (obj.answerTypes!=null && obj.answerTypes.length>0)?obj.answerTypes.length:4;
            var divWidth = 200;
            if(btnSize>4){
                divWidth = divWidth + (btnSize-4)*65;
            }
            console.log("divWidth======================"+divWidth);
            var $item = $('<div id="' + id + '" class="window nomalNode jtk-node" style="width:'+divWidth+'px;height:125px;padding: 5px 5px;">\n' +
                '                    <div class="title"  name="title" style="position:absolute;top:10px;left:5px;right:5px;color: #009688;font-weight: bold;font-size: larger;width: 100%;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;">' + obj.name + '</div>\n' +
                '                    <div class="conent" name="conent" style="text-overflow:ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;position: absolute;top: 40px;left: 5px;right: 5px">' + obj.content + '</div>\n' + buttons +
                '                </div>');

            $item.css("top", obj.y);
            $item.css("left", obj.x);
            $("#canvas").append($item);
            instance.draggable($item);
            speakingSkillList.push(obj)
        });

        $.each(JSON.parse(jsonObj.typeSkip), function (key, obj) {
            var id = obj.id;
            if (obj.id.indexOf(prefixVersion) != -1) {
                id = id.substring(0, obj.id.indexOf(prefixVersion)) + newVersion;
            } else {
                id = id + newVersion;
            }

            var $item = $('<div id="' + id + '" class="window redirectNode jtk-node " style="width:200px;height:125px;padding: 5px 5px;" >\n' +
                '                    <div class="title" style="position:absolute;top:10px;left:5px;right:5px;color: #009688;font-weight: bold;font-size: larger;width: 100%;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;">' + obj.name + '</div>\n' +
                '                    <div class="conent" style="text-overflow:ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;position: absolute;top: 40px;left: 5px;right: 5px">' + obj.content + '</div>\n' +
                '                    <div style="position:absolute;bottom:10px;left:5px;color: #009688;font-weight: bold;font-size: larger;">跳转到:' + obj.nextflowName + '</div>\n' +
                '                </div>');
            $("#canvas").append($item);
            $item.css("top", obj.y);
            $item.css("left", obj.x);
            instance.draggable($item);
            speakingSkillList.push(obj);
        });

        $.each(JSON.parse(jsonObj.connectPointsStr), function (key, point) {
            var sourceArr = [];
            var targetArr = [];
            if (point.type == "source") {
                sourceArr.push(point.location);
            } else {
                targetArr.push(point.location);
            }
            // console.log(point.elementId + "=======" + oldVersion + "=======" + newVersion);
            // var newid = point.elementId.replace(oldVersion,newVersion);
            var newid = point.elementId;
            if (point.elementId.indexOf(prefixVersion) != -1) {
                newid = point.elementId.substring(0, point.elementId.indexOf(prefixVersion)) + newVersion;
            } else {
                newid = point.elementId + newVersion;
            }
            _addEndpoints(newid, sourceArr, targetArr);
        });

        $.each(JSON.parse(jsonObj.connectRelationStr), function (key, obj) {
            var newSourceId = obj.sourceId;
            var newTargetId = obj.targetId;
            if (obj.sourceId.indexOf(prefixVersion) != -1) {
                newSourceId = obj.sourceId.substring(0, obj.sourceId.indexOf(prefixVersion)) + newVersion;
            } else {
                newSourceId = obj.sourceId + newVersion;
            }
            if (obj.targetId.indexOf(prefixVersion) != -1) {
                newTargetId = obj.targetId.substring(0, obj.targetId.indexOf(prefixVersion)) + newVersion;
            } else {
                newTargetId = obj.targetId + newVersion;
            }
            obj.sourceConnectLocation = newSourceId + obj.sourceConnectLocation;
            obj.targetConnectLocation = newTargetId + obj.targetConnectLocation;
            instance.connect({uuids: [obj.sourceConnectLocation, obj.targetConnectLocation], editable: true});
        });
    });


    //删除当前节点
    $(document).on('click', '.nodeMenu .deleteNode', function (e) {
        console.log("删除当前节点");
        try {
            var $currentNode;
            var currentId;
            if ($(currentNode).hasClass('jtk-node')) {
                $currentNode = $(currentNode)
            } else {
                $currentNode = $(currentNode).closest('.jtk-node')
            }
            delNode($currentNode);
        } catch (e) {
            console.log(e.message)
        }
    });


    //导出当前流程结果 ===》 保存到当前的flowobj对象中
    $(document).on('click', '#exportCurFlow', function (e) {
        if(seletFlowId!="0"){//判断为切换流程情况下 ===》保存当前的流程，再进行切换操作
            exportCurrentFlow();
        }

        $.each(existsFlowObjs,function (index,obj) {
            if(obj.flowId == seletFlowId){
                var submitData = {};
                submitData["typeSkip"] = skipStepStr;
                submitData["typeCommon"] = commonStepStr;
                submitData["connectPointsStr"] = connectPointsStr;
                submitData["connectRelationStr"] = connectRelationStr;
                obj.flowJsonStr = JSON.stringify(submitData);
            }
        });

        $.each($(".flowDiv"),function () {
            if($(this).attr("id") == curSelFlowId){
                seletFlowId = curSelFlowId;
                $(this).css("border-color","#E2184D");
            }else{
                $(this).css("border-color","#0A7BFA");
            }
        });
        //暂存当前的===窗体
        $("#reset").click();
    });

    //缩放 --- 缩放==》相当于整个缩放
    /**
     var zoom =0.5;
     var transformOrigin = [ 0.5, 0.5 ];
     el = instance.getContainer();
     var p = [ "webkit", "moz", "ms", "o" ],
     s = "scale(" + zoom + ")",
     oString = (transformOrigin[0] * 100) + "% " + (transformOrigin[1] * 100) + "%";

     for (var i = 0; i < p.length; i++) {
                el.style[p[i] + "Transform"] = s;
                el.style[p[i] + "TransformOrigin"] = oString;
            }

     el.style["transform"] = s;
     el.style["transformOrigin"] = oString;
     console.log(instance.getZoom());
     instance.setZoom(zoom);
     instance.repaintEverything();
     jsPlumb.fire("jsPlumbDemoLoaded", instance);
     console.log(instance.getZoom());
     * */

    function delNode(currentNode) {
        var $currentNode = $(currentNode);
        var currentId = $currentNode.attr('id');
        var sourceConn = instance.getConnections({source: currentId});
        $.each(sourceConn, function (scopeName, conn) {
            instance.deleteConnection(conn);
        });

        //获得当前节点的目标数据连接，并删除该连接
        var targetConn = instance.getConnections({target: currentId});
        $.each(targetConn, function (scopeName, conn) {
            instance.deleteConnection(conn);
        });
        var endPoints = instance.getEndpoints(currentId);
        $.each(endPoints, function (scopeName, point) {
            instance.deleteEndpoint(point);
        });
        $currentNode.find(".divButton").children().each(function (idx, elem) {
            var elem = $(elem);
            var endPoints = instance.getEndpoints(elem.attr("id"));
            $.each(endPoints, function (scopeName, point) {
                instance.deleteEndpoint(point);
            });
        });
        $currentNode.remove();
        $('.todoMenu').css({'display': 'none'});

        var newArray = [];
        //移除集合中的
        if (speakingSkillList != null && speakingSkillList.length <= 0) {
            $.each(speakingSkillList, function (key, obj) {
                if (obj.id != currentId) {
                    newArray.push(obj);
                }
            });
            speakingSkillList = newArray;
        }
    }

    /*删除连线*/
    instance.bind('contextmenu', function (c, e) {
        currentConnection = c;
    });
    $(document).on('click', '.pathMenu .deletePath', function () {
        instance.deleteConnection(currentConnection); //删除连线
        $('.todoMenu').css({'display': 'none'});
    });

    //编辑当前节点
    $(document).on('click', '.nodeMenu .editNode', function (e) {
        console.log("编辑当前节点");
        var $currentNode;
        var currentId;
        if ($(currentNode).hasClass('jtk-node')) {
            $currentNode = $(currentNode)
        } else {
            $currentNode = $(currentNode).closest('.jtk-node')
        }
        currentId = $currentNode.attr('id');
        if (currentId.indexOf(prefixVersion) != -1) {
            currentId = currentId.substring(0, currentId.indexOf(prefixVersion));
        }
        var currentObj = null;
        $.each(speakingSkillList, function () {
            if (this.id == currentId) {
                currentObj = this;
                return;
            }
        });

        $('.todoMenu').css({'display': 'none'});
        if (currentObj != null) {
            var flowJsonObj = $("#" + seletFlowId);
            editNode(currentId, currentObj);
        } else {
            layer.msg("操作异常!")
        }
    });


    /*以下为操作函数*/
    var currentNode; //当前操作的节点
    var currentConnection; //当前连线
    $('#canvas').on('contextmenu', function (e) {
        e = e || event;
        target = e.target || e.srcElement;
        currentNode = target;
        if ($(target).hasClass('jtk-node') || $(target).hasClass('jtk-endpoint-anchor') || $(target).hasClass('jtk-endpoint') || ($(target).parent != null && $(target).parent().hasClass('jtk-node'))) {
            var $menu = $('.nodeMenu');
            toggleMenu($menu, e, true);
        } else if ($(target).attr("id") == "canvas") {
            return false;
        } else {
            var $menu = $('.pathMenu');
            toggleMenu($menu, e, true);
        }
        return false;
    });
    $('#canvas').on('click', function (e) {
        $('.todoMenu').css({'display': 'none'})
    });



    /*menu操作*/
    function toggleMenu($menu, e, flag) {
        $('.todoMenu').css({'display': 'none'});
        if (flag) {
            $menu.css({"display": 'block', 'position': 'fixed', 'zIndex': '20'});
            $menu.css({'left': e.clientX, 'top': e.clientY})
        } else {
            $menu.css({'display': 'none'})
        }
    }
});


/**
 * 话术对象
 * id                id
 * x                 所在的x坐标
 * y                 所在的y坐标
 * name              节点名
 * keyWord           关键词
 * content           提示话术
 * answer            答法
 * answerTypes       按钮         多个以逗号隔开
 * flowId            所属哪个流程
 * type              流程节点类型  SpeakingFlowStepType
 * other             其他设置，多个以key_value形式存储
 * packageId         所在的话术包id
 */
var CommonObj = {
    buildParam: function (id, x, y, name, keyWord, content, answerTypeRelation, answerTypes, other) {
        var commonObj = {};
        commonObj.id = id;
        commonObj.x = x;
        commonObj.y = y;
        commonObj.name = name;
        commonObj.keyWord = keyWord;
        commonObj.content = content;
        commonObj.answerTypeRelation = answerTypeRelation;
        commonObj.answerTypes = answerTypes;
        commonObj.other = other;
        commonObj.flowId = flowId;
        commonObj.type = typeCommon;
        commonObj.packageId = packageId;
        return commonObj;
    }
};

/**
 * 跳转话术
 * id              id
 * x               所在的x坐标
 * y               所在的y坐标
 * name            节点名称
 * skipType        跳转到 指定流程、指定主动流程
 * skipFlowId      跳转到 指定流程的id
 * content         提示话术
 * desc            描述
 * packageId         所在的话术包id
 * */
var SkipObj = {
    buildParam: function (id, x, y, name, skipType, content, skipFlowId) {
        var skipObj = {};
        skipObj.id = id;
        skipObj.x = x;
        skipObj.y = y;
        skipObj.name = name;
        skipObj.content = content;
        skipObj.skipFlowId = skipFlowId;
        skipObj.skipType = skipType;
        skipObj.flowId = flowId;
        skipObj.type = typeSkip;
        skipObj.packageId = packageId;
        return skipObj;
    }
};


/**
 *连接关系
 * sourceId              连接点
 * sourceConnectLocation 连接点所在位置
 * targetId              被连接点 （箭头指向点）
 * targetConnectLocation 被连接点所在位置
 * label                 连接注释
 * id                    连接点id  用于标识唯一性，免取重复的连接关系
 * type                  自定义回答类型
 * */
var ConnectRelationObj = {
    buildParam: function (id, sourceId, sourceConnectLocation, targetId, targetConnectLocation, type, label) {
        var connectRelation = {};
        connectRelation.id = id;
        connectRelation.sourceId = sourceId;
        connectRelation.sourceConnectLocation = sourceConnectLocation;
        connectRelation.targetId = targetId;
        connectRelation.targetConnectLocation = targetConnectLocation;
        connectRelation.type = type;
        connectRelation.label = label;
        return connectRelation;
    }
};

/**
 *连接点
 * elementId    对象的话术id
 * type         类型  连接点[source]  被连接点[target]
 * location     位置
 * text         文本信息
 * */
var ConnectPointObj = {
    buildParam: function (elementId, type, location, text) {
        var connectPoint = {};
        connectPoint.elementId = elementId;
        connectPoint.type = type;
        connectPoint.location = location;
        connectPoint.text = text;
        return connectPoint;
    }
};

var speakingSkillList = [];//新增的话术集合
var commonStepStr, skipStepStr, connectPointsStr, connectRelationStr;//话术
var version = 1000000;//当前操作流程的版本号
//需要定位到指定的版本号
var prefixVersion = "_Version:";


/**编辑节点时，更新数据
 * 1、更新speakingSkillList集合的数据，导出/保存流程时用
 * 2、更新对应的flow节点的value，用于reset对应的flow的流程图数据
 *
 * 根据现有的数据 ===  提取出 currentObj 原来的数据信息
 * 跟参数的currentObj进行比对获取
 */
function updateSpeakingSkillList(currentObj) {
    console.log(currentObj);
    //比对新旧值
    var oldCurrentObj = null;
    $.each(speakingSkillList, function () {
        if (this.id == currentObj.id) {
            oldCurrentObj = this;
            delete  speakingSkillList[speakingSkillList.indexOf(this)];
            speakingSkillList.push(currentObj);
        }
    });

    if (oldCurrentObj == null) {
        return;
    }
    var flowJsonObj = $("#" + seletFlowId);
    var currentVersion = prefixVersion + version;//当前版本号
    // console.log(connectPointsStr);
    // console.log(connectRelationStr);

    var objExistsConnPointEleId = [];
    var existsConnectPoint = [];//存在的连接点
    if (currentObj.type == typeCommon) {
        var connectPoints = JSON.parse(connectPointsStr);
        var typeCommonJsonObj = JSON.parse(commonStepStr);
        var connectRelation = JSON.parse(connectRelationStr);

        var cloneConnectRelation = connectRelation.slice(0);
        var cloneConnectPoints = connectPoints.slice(0);
        $.each(cloneConnectPoints, function (index, obj) {
            // console.log(index);
            // console.log(obj.elementId);
            // console.log(obj.elementId.indexOf(currentObj.id + prefixVersion));
            // console.log(obj.elementId.indexOf(currentObj.id));
            if (currentObj != undefined && (obj.elementId.indexOf(currentObj.id + prefixVersion)==-1 && obj.elementId.indexOf(currentObj.id)!=-1)) { // 是此节点下的按钮的连接点 进行移除  ===== 变动是连接点[按钮下的]  非被连接点，所有取连接点移除，把新的连接点还原即可
                connectPoints.splice(connectPoints.indexOf(obj), 1);
            }
        });
        // console.log(connectPoints);
        //取交集
        var resultKey = [];
        if(oldCurrentObj!=null && oldCurrentObj.answerTypes!=null){
            for (var i = 0; i < oldCurrentObj.answerTypes.length; i++) {
                var temp = oldCurrentObj.answerTypes[i];
                for (var j = 0; j < currentObj.answerTypes.length; j++) {
                    if (temp.key == currentObj.answerTypes[j].key) {
                        resultKey.push(temp.key);
                        break;
                    }
                }
            }
        }

        var intersectionKeys = array_remove_repeat(resultKey);
        // console.log(intersectionKeys);
        var removeIdx = [];
        $.each(cloneConnectRelation, function (index, obj) {
            // console.log(obj.sourceId);
            // console.log(index);
            var btnType = obj.sourceId.replace(currentObj.id+"_","");
            // console.log(intersectionKeys.indexOf(btnType));
            // console.log(obj.sourceId.indexOf(currentObj.id));
            if (obj != undefined && obj.sourceId.indexOf(currentObj.id)!=-1 && intersectionKeys.indexOf(btnType)==-1) {// 按钮的连接点 且 非是交集下的按钮
                removeIdx.push(index);
                connectRelation.splice(connectRelation.indexOf(obj),1);
            }
        });

        //将原有的改成 === 现有的
        $.each(typeCommonJsonObj, function (index, obj) {
            if (obj.id == currentObj.id) {
                currentObj.x = obj.x;
                currentObj.y = obj.y;
                var idx = typeCommonJsonObj.indexOf(obj);
                typeCommonJsonObj.splice(idx, 1, currentObj);//替换 开始索引 下的第一个元素
                // console.log(typeCommonJsonObj);
                if (currentObj.answerTypes != null && currentObj.answerTypes.length > 0) { //判断节点的 回答类型
                    $.each(currentObj.answerTypes, function (index, answerObj) { //将按钮的连接点 ===》添加至 按钮连接点集合中
                        var elementId = currentObj.id + "_" + answerObj.key;
                        connectPoints.push(ConnectPointObj.buildParam(elementId + currentVersion, "source", "BottomCenter", ""));
                    });
                }
            }
        });
        commonStepStr = JSON.stringify(typeCommonJsonObj);
        connectPointsStr = JSON.stringify(connectPoints);
        connectRelationStr = JSON.stringify(connectRelation);
    } else if (currentObj.type == typeSkip || currentObj.type == typeMutiSkip ) {
        var typeSkipJsonObj = JSON.parse(skipStepStr);
        $.each(typeSkipJsonObj, function (index, obj) {
            if (obj.id == currentObj.id) {
                currentObj.x = obj.x;
                currentObj.y = obj.y;
                var idx = typeSkipJsonObj.indexOf(obj);
                typeSkipJsonObj.splice(idx, 1, currentObj);//替换 开始索引 下的第一个元素
                // console.log(typeSkipJsonObj);
            }
        });
        skipStepStr = JSON.stringify(typeSkipJsonObj);
    }

    // console.log(skipStepStr);
    // console.log(commonStepStr);
    // console.log(connectRelationStr);
    // console.log(connectPointsStr);
    var jsonData = {};//重新构建
    jsonData["typeSkip"] = skipStepStr;
    jsonData["typeCommon"] = commonStepStr;
    jsonData["connectPointsStr"] = connectPointsStr;
    jsonData["connectRelationStr"] = connectRelationStr;
    jsonStr = JSON.stringify(jsonData);
    // console.log(jsonStr);

    $.each(existsFlowObjs,function (index,obj) {
        console.log("existsFlowObjs============="+obj.flowId+"===>"+currentObj.id);
        if(obj.flowId == seletFlowId){
            obj.flowJsonStr = jsonStr;
        }
    });

    // flowJsonObj.attr("value", jsonStr);
    $("#reset").click();
}


function array_remove_repeat(a) { // 去重
    var r = [];
    for (var i = 0; i < a.length; i++) {
        var flag = true;
        var temp = a[i];
        for (var j = 0; j < r.length; j++) {
            if (temp == r[j]) {
                flag = false;
                break;
            }
        }
        if (flag) {
            r.push(temp);
        }
    }
    return r;
}

function array_intersection(a, b) { // 交集
    var result = [];
    for (var i = 0; i < b.length; i++) {
        var temp = b[i];
        for (var j = 0; j < a.length; j++) {
            if (temp == a[j]) {
                result.push(temp);
                break;
            }
        }
    }
    return array_remove_repeat(result);
}

function array_union(a, b) { // 并集
    return array_remove_repeat(a.concat(b));
}

function array_difference(a, b) { // 差集 a - b
    //clone = a
    var clone = a.slice(0);
    for (var i = 0; i < b.length; i++) {
        var temp = b[i];
        for (var j = 0; j < clone.length; j++) {
            if (temp == clone[j]) {
                //remove clone[j]
                clone.splice(j, 1);
            }
        }
    }
    return array_remove_repeat(clone);
}
